#include <stdio.h>
#include <stdlib.h>

#include <davint/davint.h>

#include <utils/msp430lib.h>
#include <pthread.h>

#include "text.h"
#include "ui.h"

#ifdef __DEBUG__
#define __E(fmt, args...) fprintf(stderr, "UI ERROR [%d]: " fmt, __LINE__, ## args)
#define __W(fmt, args...) fprintf(stderr, "UI WARNING [%d]: " fmt, __LINE__, ## args)
#else
#define __E(fmt, args...)
#define __W(fmt, args...)
#endif

// Janela de login -------------------------------------------------------------
#define LOGIN_EDITBOX_W 225
#define LOGIN_EDITBOX_X (SCREEN_WIDTH / 2 - LOGIN_EDITBOX_W / 2)
#define LOGIN_EDITBOX_Y 230
#define PASSWORD_EDITBOX_W LOGIN_EDITBOX_W
#define PASSWORD_EDITBOX_X (SCREEN_WIDTH / 2 - LOGIN_EDITBOX_W / 2)
#define PASSWORD_EDITBOX_Y (LOGIN_EDITBOX_Y + 50)

static signed int login_window_init();
static signed int login_authenticate(); // POR ENQUANTO, APENAS TESTE
static signed int login_window_ok(void *paramp, unsigned int paramsize);
static signed int login_window_enter(void *paramp, unsigned int paramsize);
static signed int login_window_addChar(void *paramp, unsigned int paramsize);
static signed int login_window_delChar(void *paramp, unsigned int paramsize);

static signed int login_window_ok_listener;
static signed int login_window_enter_listener;
static signed int login_window_addChar_listener;
static signed int login_window_delChar_listener;

static signed int login_window;
static signed int login_label;
static signed int password_label;
static signed int login_editbox;
static signed int password_editbox;
// -----------------------------------------------------------------------------

// Janela do menu principal ----------------------------------------------------
static signed int main_menu_window_init();
static signed int main_menu_ok(void *paramp, unsigned int paramsize);
static signed int main_menu_enter(void *paramp, unsigned int paramsize);
static signed int main_menu_up(void *paramp, unsigned int paramsize);
static signed int main_menu_down(void *paramp, unsigned int paramsize);

static signed int main_menu_ok_listener;
static signed int main_menu_enter_listener;
static signed int main_menu_up_listener;
static signed int main_menu_down_listener;

static signed int main_menu_window;
static signed int main_menu_history_button;
static signed int main_menu_new_patient_button;
// -----------------------------------------------------------------------------

// Janela de pesquisa de paciente ----------------------------------------------
static signed int search_window_init();

static signed int search_window;
static signed int search_window_name_label;
static signed int search_window_SUS_label;
static signed int search_window_name_editbox;
static signed int search_window_SUS_editbox;
static signed int search_window_info_multieditbox;
static signed int search_window_image;
static signed int search_window_ok_button;
// -----------------------------------------------------------------------------

// Janela de exibição de imagens -----------------------------------------------

// -----------------------------------------------------------------------------

// Janela de cadastro de paciente ----------------------------------------------

// -----------------------------------------------------------------------------

static signed int current_window;

signed int ui_init() {
    font_setExtraAdvanceX(2);

    if (login_window_init() == UI_FAILURE) {
        fprintf(stderr, "Erro ao inicializar a janela de login!\n");
        return UI_FAILURE;
    }

    if (main_menu_window_init() == UI_FAILURE) {
        fprintf(stderr, "Erro ao inicializar a janela do menu principal!\n");
        return UI_FAILURE;
    }

    if (search_window_init() == UI_FAILURE) {
        fprintf(stderr, "Erro ao inicializar a janela de pesquisa!\n");
        return UI_FAILURE;
    }

    window_changeActual(login_window);
    window_refresh();

    return UI_SUCCESS;
}

static signed int login_window_init() {
    signed int ui_err = 0;

    login_window = window_create(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    if (login_window == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao criar a janela de login!\n");
        return UI_FAILURE;
    }

    ui_err = window_setVisibility(login_window, 1);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao definir a visibilidade da janela de login!\n");
        return UI_FAILURE;
    }

    ui_err = window_setBackground(login_window, LOGIN_WINDOW_BACKGROUND_IMAGE);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao definir a imagem de fundo da janela de login!\n");
        return UI_FAILURE;
    }

    login_label = label_create(LOGIN_EDITBOX_X - 100, LOGIN_EDITBOX_Y + 15, 18, "Login", 100, 135, 167);
    if (login_label == LABEL_FAILURE) {
        fprintf(stderr, "Erro ao criar label do login!\n");
    }
    window_insertLabel(login_window, login_label);

    password_label = label_create(PASSWORD_EDITBOX_X - 100, PASSWORD_EDITBOX_Y + 15, 18, "Senha", 100, 135, 167);
    if (login_label == LABEL_FAILURE) {
        fprintf(stderr, "Erro ao criar label do login!\n");
    }
    window_insertLabel(login_window, password_label);

    login_editbox = editbox_create(LOGIN_EDITBOX_X, LOGIN_EDITBOX_Y, LOGIN_EDITBOX_W, 116, 151, 183, "", 16, 255, 255, 255, 5);
    if (login_editbox == EDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao criar editbox de login!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertEditbox(login_window, login_editbox);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir editbox de login na janela!\n");
        return UI_FAILURE;
    }

    editbox_select(login_editbox);

    password_editbox = editbox_create(PASSWORD_EDITBOX_X, PASSWORD_EDITBOX_Y, PASSWORD_EDITBOX_W, 116, 151, 183, "", 16, 255, 255, 255, 5);
    if (password_editbox == EDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao criar editbox de senha da janela de login!\n");
        return UI_FAILURE;
    }

    ui_err = editbox_setMode_password(password_editbox);
    if (ui_err == EDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao definir o modo do editbox de senha\n");
        return UI_FAILURE;
    }

    ui_err = window_insertEditbox(login_window, password_editbox);
    if (ui_err == EDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao inserir editbox de senha na janela de login!\n");
        return UI_FAILURE;
    }

    login_window_ok_listener = listener_create(EVENT_OK, login_window_ok);
    if (login_window_ok_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener ok da janela de login\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(login_window, login_window_ok_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener ok na janela de login\n");
        return UI_FAILURE;
    }

    login_window_enter_listener = listener_create(EVENT_ENTER, login_window_enter);
    if (login_window_enter_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener enter da janela de login\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(login_window, login_window_enter_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener enter na janela de login\n");
        return UI_FAILURE;
    }

    login_window_addChar_listener = listener_create(EVENT_ADD_CHAR, login_window_addChar);
    if (login_window_addChar_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener addChar da janela de login\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(login_window, login_window_addChar_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener addChar na janela de login\n");
        return UI_FAILURE;
    }

    login_window_delChar_listener = listener_create(EVENT_DEL_CHAR, login_window_delChar);
    if (login_window_delChar_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener delChar da janela de login\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(login_window, login_window_delChar_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener delChar na janela de login\n");
        return UI_FAILURE;
    }

    return UI_SUCCESS;
}

static signed int login_authenticate() {
    char login[EDITBOX_MAX_TEXT];
    char password[EDITBOX_MAX_TEXT];

    memset((void *) login, '\0', EDITBOX_MAX_TEXT);
    memset((void *) password, '\0', EDITBOX_MAX_TEXT);

    if (editbox_getText(login_editbox, &login) == EDITBOX_FAILURE) {
        fprintf(stderr, "login_authenticate: editbox_getText falhou para o login\n");
        return UI_FAILURE;
    }

    if (editbox_getText(password_editbox, &password) == EDITBOX_FAILURE) {
        fprintf(stderr, "login_authenticate: editbox_getText falhou para o password\n");
        return UI_FAILURE;
    }

    printf("login_authenticate --> login: %s\n", login);
    printf("login_authenticate --> password: %s\n", password);

    // if (login e senha corretos) {
    if (window_changeActual(main_menu_window) == WINDOW_FAILURE) {
        fprintf(stderr, "login_authenticate: window_changeActual falhou\n");
        return UI_FAILURE;
    }
    //} else {
    //return AUTH_FAILURE;
    //
    return UI_SUCCESS;
}

static signed int login_window_ok(void *paramp, unsigned int paramsize) {
    signed int ui_err;

    signed int window_enable = window_getEnable();
    if (window_enable != login_window) {
        fprintf(stderr, "login_window_ok: Janela ativa incorreta!\n");
        return LISTENER_FAILURE;
    }

    ui_err = login_authenticate();
    if (ui_err == UI_FAILURE) {
        fprintf(stderr, "login_window_ok: login_authenticate falhou\n");
        return LISTENER_FAILURE;
    } else if (ui_err == AUTH_FAILURE) {
        // FALHA NA AUTENTICAÇÃO
    }
    return LISTENER_SUCCESS;
}

static signed int login_window_enter(void *paramp, unsigned int paramsize) {
    signed int ui_err;

    signed int window_enable = window_getEnable();
    if (window_enable != login_window) {
        fprintf(stderr, "login_window_enter: Janela ativa incorreta!\n");
        return LISTENER_FAILURE;
    }

    if (window_nextEditbox(window_enable) == login_editbox) {
        ui_err = login_authenticate();
        if (ui_err == UI_FAILURE) {
            fprintf(stderr, "login_window_enter: login_authenticate falhou\n");
            return LISTENER_FAILURE;
        } else if (ui_err == AUTH_FAILURE) {
            // FALHA NA AUTENTICAÇÃO
        }
    }
    return LISTENER_SUCCESS;
}

static signed int login_window_addChar(void *paramp, unsigned int paramsize) {
    char text[EDITBOX_MAX_TEXT];

    if (paramsize != 1) {
        fprintf(stderr, "login_window_addChar: Parâmetro incorreto!\n");
        return LISTENER_FAILURE;
    }

    int window_enable = window_getEnable();
    if (window_enable != login_window) {
        fprintf(stderr, "login_window_addChar: Janela ativa incorreta!\n");
        return LISTENER_FAILURE;
    }

    int editbox_selected = window_inform_actualEditbox_selected(window_enable);
    if (editbox_selected != EDITBOX_FAILURE) {
        if (editbox_getText(editbox_selected, &text) == EDITBOX_FAILURE) {
            fprintf(stderr, "login_window_addChar: editbox_getText falhou\n");
            return LISTENER_FAILURE;
        }
        if (text_addChar(text, *((unsigned char *) paramp)) == TEXT_FAILURE) {
            __E("login_window_addChar: text_addChar falhou\n");
            return LISTENER_FAILURE;
        } else {
            if (editbox_setText(editbox_selected, text) == EDITBOX_FAILURE) {
                __E("login_window_addChar: editbox_setText falhou\n");
                return LISTENER_FAILURE;
            }
        }
    }
    return LISTENER_SUCCESS;
}

static signed int login_window_delChar(void *paramp, unsigned int paramsize) {
    char text[EDITBOX_MAX_TEXT];

    if (paramsize != 0) {
        fprintf(stderr, "login_window_delChar: Parâmetro incorreto!\n");
        return LISTENER_FAILURE;
    }

    int window_enable = window_getEnable();
    if (window_enable != login_window) {
        fprintf(stderr, "login_window_delChar: Janela ativa incorreta!\n");
        return LISTENER_FAILURE;
    }

    int editbox_selected = window_inform_actualEditbox_selected(window_enable);
    if (editbox_selected != EDITBOX_FAILURE) {
        if (editbox_getText(editbox_selected, &text) == EDITBOX_FAILURE) {
            fprintf(stderr, "login_window_delChar: editbox_getText falhou\n");
            return LISTENER_FAILURE;
        }
        text_delChar(text);
        if (editbox_setText(editbox_selected, text) == EDITBOX_FAILURE) {
            fprintf(stderr, "login_window_delChar: editbox_setText falhou\n");
            return LISTENER_FAILURE;
        }
    }
    return LISTENER_SUCCESS;
}

static signed int main_menu_window_init() {
    signed int ui_err = 0;

    main_menu_window = window_create(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    if (main_menu_window == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao criar a janela do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_setVisibility(main_menu_window, 1);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao definir a visibilidade da janela do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_setBackground(main_menu_window, MAIN_MENU_WINDOW_BACKGROUND_IMAGE);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao definir a imagem de fundo da janela do menu principal!\n");
        return UI_FAILURE;
    }

    main_menu_history_button = button_create(150, 150, 50, 320, 116, 151, 183, "Historico de paciente", 15, 255, 255, 255);
    if (main_menu_history_button == BUTTON_FAILURE) {
        fprintf(stderr, "Erro ao criar botao de historico do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertButton(main_menu_window, main_menu_history_button);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir botão de histórico do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = button_select(main_menu_history_button);
    if (ui_err == BUTTON_FAILURE) {
        fprintf(stderr, "Erro ao selecionar o botão de histórico do menu principal!\n");
        return UI_FAILURE;
    }

    main_menu_new_patient_button = button_create(150, 250, 50, 320, 116, 151, 183, "Editar dados do paciente", 15, 255, 255, 255);
    if (main_menu_new_patient_button == BUTTON_FAILURE) {
        fprintf(stderr, "Erro ao criar botao de cadastro do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertButton(main_menu_window, main_menu_new_patient_button);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir botão de edição no menu principal!\n");
        return UI_FAILURE;
    }

    main_menu_ok_listener = listener_create(EVENT_OK, main_menu_ok);
    if (main_menu_ok_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener ok do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(main_menu_window, main_menu_ok_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener ok no menu principal!\n");
        return UI_FAILURE;
    }

    main_menu_enter_listener = listener_create(EVENT_ENTER, main_menu_ok);
    if (main_menu_enter_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener enter do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(main_menu_window, main_menu_enter_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener enter no menu principal!\n");
        return UI_FAILURE;
    }

    main_menu_up_listener = listener_create(EVENT_UP, main_menu_up);
    if (main_menu_up_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener up do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(main_menu_window, main_menu_up_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener up no menu principal!\n");
        return UI_FAILURE;
    }

    main_menu_down_listener = listener_create(EVENT_DOWN, main_menu_down);
    if (main_menu_down_listener == LISTENER_FAILURE) {
        fprintf(stderr, "Erro ao criar o listener down do menu principal!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertListener(main_menu_window, main_menu_down_listener);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir o listener down no menu principal!\n");
        return UI_FAILURE;
    }

    return UI_SUCCESS;
}

static signed int main_menu_ok(void *paramp, unsigned int paramsize) {

	int button_selected = window_inform_actualButton_selected(main_menu_window);

	if (button_selected == main_menu_history_button) {
		window_changeActual(search_window);
	} else if (button_selected = main_menu_new_patient_button) {
		printf("Editar dados\n");
//		window_changeActual();
	}

    return LISTENER_SUCCESS;
}

static signed int main_menu_up(void *paramp, unsigned int paramsize) {

	if (window_previousButton(main_menu_window) == WINDOW_FAILURE) {
		return LISTENER_SUCCESS;
	} else {
	    return LISTENER_FAILURE;
	}
}

static signed int main_menu_down(void *paramp, unsigned int paramsize) {
	
	if (window_nextButton(main_menu_window) == WINDOW_FAILURE) {
		return LISTENER_SUCCESS;
	} else {
	    return LISTENER_FAILURE;
	}
}

static signed int search_window_init() {
    signed int ui_err = 0;

    search_window = window_create(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    if (search_window == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao criar a janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_setVisibility(search_window, 1);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao definir a visibilidade da janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_setBackground(search_window, SEARCH_WINDOW_BACKGROUND_IMAGE);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao definir a imagem de fundo da janela de pesquisa!\n");
        return UI_FAILURE;
    }

    search_window_name_label = label_create(50, 50, 18, "Nome", 100, 135, 167);
    if (search_window_name_label == LABEL_FAILURE) {
        fprintf(stderr, "Erro ao criar label de nome da janela de pesquisa!\n");
    }
    window_insertLabel(search_window, search_window_name_label);

    search_window_SUS_label = label_create(60, 110, 18, "SUS", 100, 135, 167);
    if (search_window_SUS_label == LABEL_FAILURE) {
        fprintf(stderr, "Erro ao criar label de SUS da janela de pesquisa!\n");
    }
    window_insertLabel(search_window, search_window_SUS_label);

    search_window_name_editbox = editbox_create(150, 40, 230, 116, 151, 183, "", 16, 255, 255, 255, 5);
    if (search_window_name_editbox == EDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao criar editbox de nome da janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertEditbox(search_window, search_window_name_editbox);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir editbox de nome na janela de pesquisa!\n");
        return UI_FAILURE;
    }

    editbox_select(search_window_name_editbox);

    search_window_SUS_editbox = editbox_create(150, 100, 230, 116, 151, 183, "", 16, 255, 255, 255, 5);
    if (search_window_SUS_editbox == EDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao criar editbox de SUS da janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertEditbox(search_window, search_window_SUS_editbox);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir editbox de SUS na janela de pesquisa!\n");
        return UI_FAILURE;
    }

    search_window_info_multieditbox = multieditbox_create(8, 60, 180, 300, 15, 255, 255, 255, 0, 0, 0);
    if (search_window_info_multieditbox == MULTIEDITBOX_FAILURE) {
        fprintf(stderr, "Erro ao criar multieditbox de informacoes da janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertMultieditbox(search_window, search_window_info_multieditbox);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir multieditbox de informacoes na janela de pesquisa!\n");
        return UI_FAILURE;
    }

    multieditbox_setText(search_window_info_multieditbox, "Informacoes sobre o   paciente:");

    search_window_image = image_create(370, 180, "data/pics/bleh200x200.png");
    if (search_window_image == IMAGE_FAILURE) {
        fprintf(stderr, "Erro ao criar imagem do paciente na janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertImage(search_window, search_window_image);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir imagem do paciente na janela de pesquisa!\n");
        return UI_FAILURE;
    }

    search_window_ok_button = button_create(430, 102, editbox_getHeight(search_window_name_editbox) - 5, 230, 116, 151, 183, "Pesquisar", 16, 255, 255, 255);
    if (search_window_ok_button == BUTTON_FAILURE) {
        fprintf(stderr, "Erro ao criar botao OK da janela de pesquisa!\n");
        return UI_FAILURE;
    }

    ui_err = window_insertButton(search_window, search_window_ok_button);
    if (ui_err == WINDOW_FAILURE) {
        fprintf(stderr, "Erro ao inserir botao OK na janela de pesquisa!\n");
        return UI_FAILURE;
    }

    return UI_SUCCESS;
}
